package cn.teammade.sms.common.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;

public class RedisUtils {

	private static Logger logger = Logger.getLogger(RedisUtils.class);
	

	private JedisPool jedisPool;

	/**
	 * key对应的Value加1 原子性操作
	 * @param key
	 */
	public Long incr(String key) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			return jedis.incr(key);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
		return null;
	}

	/**
	 * key对应的Value减1 原子性操作
	 * @param key
	 */
	public Long decr(String key) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			return jedis.decr(key);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
		return null;
	}

	/**
	 * key对应的Value加 increment 原子性操作
	 * @param key
	 */
	public Long incrBy(String key, long increment) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			return jedis.incrBy(key, increment);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
		return null;
	}

	/**
	 * key对应的Value减decrement 原子性操作
	 * @param key
	 */
	public Long decrBy(String key, long decrement) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			return jedis.decrBy(key, decrement);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
		return null;
	}

	/**
	 * Hash 操作 HSET key field value将哈希表key中的域field的值设为value
	 * @param key
	 * @param field
	 * @param value
	 */
	public void hset(String key, String field, String value) {

		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.hset(key, field, value);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}

	}

	/**
	 * Hash 操作 HSET key field value将哈希表key中的域field的值设为value
	 * @param key
	 * @param field
	 * @param value
	 * @param expire 有效期 单位是ms
	 */
	public void hset(String key, String field, String value, long expire) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.hset(key, field, value);
			jedis.expire(key, Long.valueOf(expire / 1000).intValue());
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
	}

	/**
	 * 获取hash的所有keys
	 * @param key
	 * @return
	 */
	public Set<String> hkeys(String key) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			Set<String> hkeys = jedis.hkeys(key);
			return hkeys;
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				//jedis.close();
				jedisPool.returnResource(jedis);
			}
		}
		return null;
	}

	/**
	 * HDEL key field [field ...]删除哈希表key中的一个或多个指定域。
	 * @param key
	 * @param fields
	 */
	public void hdel(String key, String... fields) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.hdel(key, fields);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				//jedis.close();
				jedisPool.returnResource(jedis);
			}
		}
	}

	/**
	 * GET key field返回哈希表key中给定域field的值
	 * @param key
	 * @param field
	 * @return
	 */
	public String hget(String key, String field) {
		if (StringUtils.isBlank(field)) {
			return null;
		}
		String value = null;
		Jedis jedis = null;
		try {
			//if (jedis == null) {
			jedis = jedisPool.getResource();
			//}
			value = jedis.hget(key, field);

		} catch (Exception ex) {
			ex.printStackTrace();
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				//jedis.close();
				jedisPool.returnResource(jedis);
			}
		}
		return value;
	}

	/**
	 * 判断是否存在field
	 * @param key
	 * @param field
	 * @return
	 */

	public Boolean exists(String key) {

		Jedis jedis = null;
		Boolean ret = null;
		try {
			jedis = jedisPool.getResource();
			ret = jedis.exists(key);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
		return ret;

	}

	/**
	 * 判断是否存在field
	 * @param key
	 * @param field
	 * @return
	 */

	public Boolean hexists(String key, String field) {

		Jedis jedis = null;
		Boolean ret = null;

		try {
			jedis = jedisPool.getResource();
			ret = jedis.hexists(key, field);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
		return ret;

	}

	public List<String> phget(List<String> keyList) {
		Jedis jedis = null;
		List<String> value = new ArrayList<String>();
		int count = 0;
		try {
			jedis = jedisPool.getResource();
			Pipeline p = jedis.pipelined();
			int i = 0;
			for (String key : keyList) {
				p.del(key);
				/*
				 * Response<Map<String, String>> ss1 =p.hgetAll(key); Map<String, String> ss = ss1.get(); Set<String>
				 * sese = ss.keySet(); for(String s : sese){ jedis.hset(key, s, "0"); }
				 */
				/*
				 * 286132 2014-12-04 302111 2014-12-03 279450 2014-12-02 207426 2014-12-01 141240 2014-11-30 146152
				 * 2014-11-29 159967 2014-11-28 113284 2014-11-27 92598 2014-11-26 66940 2014-11-25 28586 2014-11-24
				 * 6956 2014-11-23 4149 2014-11-22 7 2014-11-21
				 */
				System.out.println(i++);
			}
			p.sync();
			/*
			 * List<Object> rs = p.syncAndReturnAll(); for (Object r : rs) { if (null != r &&
			 * Boolean.parseBoolean(r.toString())) { // value.add(r.toString()); count++; } }
			 */
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
		logger.info(count + "");
		return value;
	}

	/**
	 * 得到复杂对象的值
	 * @param key
	 * @return
	 */
	public Map<String, String> hgetAll(String key) {
		Jedis jedis = null;
		Map<String, String> value = null;
		try {
			jedis = jedisPool.getResource();
			value = jedis.hgetAll(key);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
		return value;
	}

	/**
	 * GET key field返回哈希表key中给定域field的值
	 * @param key
	 * @param field
	 * @param refreshSource
	 * @param expiry 有效期
	 * @return
	 */
	public String hget(String key, String field, Callable<String> refreshSource, long expiry) {
		String value = hget(key, field);
		if (null == value) {
			try {
				value = refreshSource.call();
				if (null != value) {
					hset(key, field, value, expiry);
				}
			} catch (Exception ex) {
				logger.error(ex.getMessage(), ex);
			}
		}
		return value;
	}

	/**
	 * GET key field返回哈希表key中给定域field的值
	 * @param key
	 * @param field
	 * @param refreshSource
	 * @return
	 */
	public String hget(String key, String field, Callable<String> refreshSource) {
		String value = hget(key, field);
		if (null == value) {
			try {
				value = refreshSource.call();
				if (null != value) {
					hset(key, field, value);
				}
			} catch (Exception ex) {
				logger.error(ex.getMessage(), ex);
			}
		}
		return value;
	}

	/**
	 * 设值
	 * @param key
	 * @param value
	 */
	public void set(String key, String value) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.set(key, value);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
	}

	/**
	 * set类型设值
	 * @param key
	 * @param value
	 * @param expire 有效期 单位是ms
	 */
	public void set(String key, String value, long expire) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.set(key, value);
			jedis.expire(key, Long.valueOf(expire / 1000).intValue());
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
	}

	/**
	 * set类型设值
	 * @param key
	 * @param value
	 */
	public void sadd(String key, String... values) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.sadd(key, values);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
	}

	/**
	 * set类型设值
	 * @param key
	 * @param value
	 * @param expire 有效期 单位是ms
	 */
	public void sadd(long expire, String key, String... values) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.sadd(key, values);
			jedis.expire(key, Long.valueOf(expire / 1000).intValue());
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
	}

	/**
	 * set类型得到值
	 * @param key
	 * @return
	 */
	public Set<String> sget(String key) {
		Jedis jedis = null;
		Set<String> value = null;
		try {
			jedis = jedisPool.getResource();
			value = jedis.smembers(key);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
		return value;
	}

	/**
	 * 删除值。
	 * @param key
	 */
	public void del(String key) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.del(key);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				//jedis.close();
				jedisPool.returnResource(jedis);
			}
		}
	}

	/**
	 * 得到值
	 * @param key
	 * @return
	 */
	public String get(String key) {
		Jedis jedis = null;
		String value = null;
		try {
			jedis = jedisPool.getResource();
			value = jedis.get(key);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
		return value;
	}

	/**
	 * 得到值
	 * @param key
	 * @param refreshSource
	 * @param expiry 有效期
	 * @return
	 */
	public String get(String key, Callable<String> refreshSource, long expiry) {
		String value = get(key);
		if (null == value) {
			try {
				value = refreshSource.call();
				if (null != value) {
					set(key, value, expiry);
				}
			} catch (Exception ex) {
				logger.error(ex.getMessage(), ex);
			}
		}
		return value;
	}

	/**
	 * 得到值
	 * @param key
	 * @param refreshSource
	 * @return
	 */
	public String get(String key, Callable<String> refreshSource) {
		String value = get(key);
		if (null == value) {
			try {
				value = refreshSource.call();
				if (null != value) {
					set(key, value);
				}
			} catch (Exception ex) {
				logger.error(ex.getMessage(), ex);
			}
		}
		return value;
	}

	/**
	 * 在key对应list的头部添加字符串元素
	 * @param key
	 * @param values
	 * @return
	 */
	public Long lpush(String key, String... values) {
		Jedis jedis = null;
		Long value = null;
		try {
			jedis = jedisPool.getResource();
			value = jedis.lpush(key, values);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				//jedis.close();
				jedisPool.returnResource(jedis);
			}
		}
		return value;
	}

	/**
	 * 从list的头部删除元素，并返回删除元素
	 * @param key
	 * @return
	 */
	public String lpop(String key) {
		Jedis jedis = null;
		String value = null;
		try {
			jedis = jedisPool.getResource();
			value = jedis.lpop(key);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
		return value;
	}

	/**
	 * 在key对应list的尾部添加字符串元素
	 * @param key
	 * @param values
	 * @return
	 */
	public Long rpush(String key, String... values) {
		Jedis jedis = null;
		Long value = null;
		try {
			jedis = jedisPool.getResource();
			value = jedis.rpush(key, values);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
				//jedis.close();
			}
		}
		return value;
	}

	/**
	 * 从list的尾部删除元素，并返回删除元素
	 * @param key
	 * @return
	 */
	public String rpop(String key) {
		Jedis jedis = null;
		String value = null;
		try {
			jedis = jedisPool.getResource();
			value = jedis.rpop(key);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				//jedis.close();
				jedisPool.returnResource(jedis);
			}
		}
		return value;
	}

	/**
	 * 从list的尾部删除元素，并返回删除元素
	 * @param key
	 * @return
	 */
	public String brpop(String key) {
		Jedis jedis = null;
		List<String> list = null;
		try {
			jedis = jedisPool.getResource();
			list = jedis.brpop(0, key);

			if (list == null || list.isEmpty()) {
				return null;
			} else {
				return list.get(1);
			}
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);

		} finally {
			if (jedis != null) {
				//jedis.close();
				jedisPool.returnResource(jedis);
			}
		}
		return null;
	}

	/**
	 * 在key对应list下标的值
	 * @param key
	 * @param values
	 * @return
	 */
	public String lindex(String key, long index) {
		Jedis jedis = null;
		String value = null;
		try {
			jedis = jedisPool.getResource();
			value = jedis.lindex(key, index);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
		return value;
	}

	/**
	 * 在key对应list下标的值
	 * @param key
	 * @param values
	 * @return
	 */
	public Long llen(String key) {
		Jedis jedis = null;
		Long value = null;
		try {
			jedis = jedisPool.getResource();
			value = jedis.llen(key);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
		return value;
	}

	/**
	 * 遍历list
	 * @param key
	 * @param values
	 * @return
	 */
	public List<String> lrange(String key, Integer start, Integer end) {
		Jedis jedis = null;
		List<String> list = new ArrayList<String>();
		try {
			jedis = jedisPool.getResource();
			list = jedis.lrange(key, start, end);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				//jedis.close();
				jedisPool.returnResource(jedis);

			}
		}
		return list;
	}

	public void setJedisPool(JedisPool jedisPool) {
		this.jedisPool = jedisPool;
	}
	
	
	/**
	 * 设置过期时间
	 * @param key
	 * @param expire
	 */
	public void setExpire(String key, long expire) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.expire(key, Long.valueOf(expire / 1000).intValue());
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		} finally {
			if (jedis != null) {
				jedisPool.returnResource(jedis);
			}
		}
	}

}
